using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Windows.Forms.VisualStyles;
using System.Web.Services.Protocols;
using System.Xml;
using System.Data.Sql;
using System.Data.SqlClient;

using PSLibrary = Microsoft.Office.Project.Server.Library;

namespace RBSViewer
{
    public partial class BulkEdit : Form
    {
        private const string CUSTOMFIELDSSWEBSERVICE = "_vti_bin/PSI/CustomFields.asmx";
        private const string LOOKUPTABLESWEBSERVICE = "_vti_bin/PSI/LookupTable.asmx";
        private const string RESOURCESWEBSERVICE = "_vti_bin/PSI/Resource.asmx";
        RBSViewer.CustomFieldsWsc.CustomFields CustomFields = new RBSViewer.CustomFieldsWsc.CustomFields();
        RBSViewer.LookupTablesWsc.LookupTable LookupTable = new RBSViewer.LookupTablesWsc.LookupTable();
        RBSViewer.ResourceWsc.Resource Resource = new RBSViewer.ResourceWsc.Resource();
        String uberlist = "";
        const String assatr = "Assignment Attributes";
        const String bicfs = "Built-In Custom Fields";
        const String rescfs = "Resource Custom Fields";
        Guid tsmgrGuid = Guid.NewGuid();
        Guid defassnOwnerGuid = Guid.NewGuid();
        Guid RBSGuid =  PSLibrary.CustomField.RBS_MD_PROP_UID;
        Guid TeamNameGuid = PSLibrary.CustomField.TEAM_MD_PROP_UID;
        Guid CostTypeGuid = PSLibrary.CustomField.COST_TYPE_MD_PROP_UID;
        public static Boolean[] buttonactivationarray;
        bool resbind;

        SelectedResources[] resources;

        String[] RBSTypeNames;
        Guid[] RBSValueTypeGuids;
        CheckedItems[] mycheckeditems;
        String RdbDatabase;
        String RdbServer;

        public BulkEdit()
        {
            InitializeComponent();
        }

        public void BindData(Boolean resourceBind, Guid[] TypeGuids, String[] TypeNames, int counter, string rdsdbs, string rdsserv)
        {
            RdbDatabase = rdsdbs;
            RdbServer = rdsserv;
            ItemsTextBox.Text = "";
            CustomFields.Url = MainForm.PWAURL + CUSTOMFIELDSSWEBSERVICE;
            CustomFields.Credentials = CredentialCache.DefaultCredentials;

            LookupTable.Url = MainForm.PWAURL + LOOKUPTABLESWEBSERVICE;
            LookupTable.Credentials = CredentialCache.DefaultCredentials;

            Resource.Url = MainForm.PWAURL + RESOURCESWEBSERVICE;
            Resource.Credentials = CredentialCache.DefaultCredentials;

            resbind = resourceBind;


            if (resbind)
            {
                //We're editing resources directly
                resources = new SelectedResources[TypeGuids.Length];
                for (int i = 0; i < TypeGuids.Length; i++)
                {
                    resources[i].resGuids = TypeGuids[i];
                    resources[i].resNames = TypeNames[i];
                }
                BulkEditTypeLabel.Text = "Resources selected :";
            }
            else
            {
                //We're editing all resources under the selected RBS nodes
                RBSValueTypeGuids = TypeGuids;
                RBSTypeNames = TypeNames;
                BulkEditTypeLabel.Text = "RBS Nodes selected :";
            }

            for (int i = 0; i < counter; i++)
            {

                uberlist += TypeNames[i];
                if(i <counter-1)
                {
                    //Only add a comma when it's not the last one
                    uberlist += ", ";
                }
                ItemsTextBox.Text = uberlist;
            }

            //Now bind to the data grid
            dataGridView1.AllowUserToAddRows = false;

            DataSet ds = new DataSet();
            DataTable dt = new DataTable("ResourceFields");
            dt.Columns.Add("Heading",System.Type.GetType("System.String"));
            dt.Columns.Add("ApplyChanges", System.Type.GetType("System.Boolean"));
            dt.Columns.Add("FieldGuid",System.Type.GetType("System.Guid"));
            dt.Columns.Add("FieldName", System.Type.GetType("System.String"));
            dt.Columns.Add("LookupTableGuid", System.Type.GetType("System.Guid"));
            dt.Columns.Add("Buttons", System.Type.GetType("System.Boolean"));
            dt.Columns.Add("MultiValue", System.Type.GetType("System.Boolean"));
            dt.Columns.Add("Type", System.Type.GetType("System.Int32"));

            //Add the rows to the grid
            AddAssignmentRows(dt);
            AddBuiltInCustomFields(dt);
            AddResourceCFs(dt);

            ds.Tables.Add(dt);

            dataGridView1.DataSource = ds.Tables["ResourceFields"];
            dataGridView1.Invalidate();

            LookupTablesWsc.LookupTableDataSet myds = LookupTable.ReadLookupTables("", false, 1033);

        }

        public void AddAssignmentRows(DataTable dt)
        {
            DataRow row;
            row = AddRow(dt, assatr, tsmgrGuid, "Timesheet manager", Guid.Empty,true,"1", -1);
            dt.Rows.Add(row);

            row = dt.NewRow();
            row = AddRow(dt, assatr, defassnOwnerGuid, "Default Assignment Owner",Guid.Empty,true, "1",-1);
            dt.Rows.Add(row);
        }

        public void AddBuiltInCustomFields(DataTable dt)
        {
            DataRow row;

            row = AddSimpleRow(dt, bicfs, TeamNameGuid, "Team Name",false, 21);
            dt.Rows.Add(row);
            row = AddSimpleRow(dt, bicfs, RBSGuid, "RBS",false,21);
            dt.Rows.Add(row);
            row = AddSimpleRow(dt, bicfs, CostTypeGuid, "Cost Type",false,21);
            dt.Rows.Add(row);             
        }

        public void AddResourceCFs(DataTable dt)
        {
            DataRow row;

            RBSViewer.CustomFieldsWsc.CustomFieldDataSet ds = CustomFields.ReadCustomFieldsByEntity(new Guid(PSLibrary.EntityCollection.Entities.ResourceEntity.UniqueId));
            buttonactivationarray = new Boolean[2+ds.Tables["CustomFields"].Rows.Count];
            //Why 2? Because the CustomFields also includes the Built In CFs
            for (int i = 0; i < 2; i++)
            {
                buttonactivationarray[i] = true;
            }
            int counter = 5;
            foreach (DataRow temprow in ds.Tables["CustomFields"].Rows)
            {
                bool buttonon;
                String str = temprow["MD_LOOKUP_TABLE_UID"].ToString();
                if (str == "")
                {
                    buttonon = false;
                }
                else
                {
                    buttonon = true;
                    if (!temprow["MD_PROP_UID"].Equals(TeamNameGuid) && !temprow["MD_PROP_UID"].Equals(RBSGuid) && !temprow["MD_PROP_UID"].Equals(CostTypeGuid))
                    {
                        buttonactivationarray[counter] = buttonon;
                        String reqflag = "";
                        if (temprow["MD_PROP_IS_REQUIRED"].Equals("true"))
                            reqflag = "*";
                        if (buttonon == false)
                            row = AddSimpleRow(dt, rescfs, new Guid(temprow["MD_PROP_UID"].ToString()), reqflag + temprow["MD_PROP_NAME"].ToString(), buttonon, Convert.ToInt32(temprow["FIELD_TYPE_ENUM"].ToString()));
                        else
                            row = AddRow(dt, rescfs, new Guid(temprow["MD_PROP_UID"].ToString()), reqflag + temprow["MD_PROP_NAME"].ToString(), new Guid(str), buttonon, temprow["MD_PROP_MAX_VALUES"].ToString(), Convert.ToInt32(temprow[9].ToString()));

                        dt.Rows.Add(row);
                        counter++;
                    }
                    else
                    {
                        String reqflag = "";
                        if (temprow["MD_PROP_IS_REQUIRED"].ToString().Equals("True"))
                            reqflag = "*";
                        int counter2 = 0;
                        if (temprow["MD_PROP_UID"].Equals(TeamNameGuid))
                        {
                            counter2 = 2;
                        }
                        if (temprow["MD_PROP_UID"].Equals(RBSGuid))
                        {
                            counter2 = 3;
                        }
                        if (temprow["MD_PROP_UID"].Equals(CostTypeGuid))
                        {
                            counter2 = 4;
                        }
                        dt.Rows[counter2]["FieldName"] = reqflag + temprow["MD_PROP_NAME"].ToString();
                        dt.Rows[counter2]["Buttons"] = buttonon;
                        dt.Rows[counter2]["LookupTableGuid"] = new Guid(str);
                        buttonactivationarray[counter2] = buttonon;
                    }

                }

            }
        }

        public DataRow AddSimpleRow(DataTable dt, string heading, Guid FieldGuid, String FieldName, Boolean activebutton, int type)
        {
            DataRow row;
            row = dt.NewRow();
            row["Heading"] = heading;
            row["ApplyChanges"] = false;
            row["FieldGuid"] = FieldGuid;
            row["FieldName"] = FieldName;
            row["Buttons"] = activebutton;
            row["MultiValue"] = false;
            row["Type"] = type;
            return row;
        }


        public DataRow AddRow(DataTable dt, string heading, Guid FieldGuid, String FieldName, Guid LookupTableGuid, Boolean activebutton, String Multivalue, int type)
        {
            DataRow row;
            row = dt.NewRow();
            row["Heading"] = heading;
            row["ApplyChanges"] = false;
            row["FieldGuid"] = FieldGuid;
            row["FieldName"] = FieldName;
            row["LookupTableGuid"] = LookupTableGuid;
            row["Buttons"] = activebutton;
            row["MultiValue"] = false;
            if(!Multivalue.Equals("1"))
            {
                row["MultiValue"] = true;
            }
            row["Type"] = type;
            return row;
        }

        private void Cancel_Click(object sender, EventArgs e)
        {
            uberlist = "";
            this.Hide();
        }

        private void Save_Click(object sender, EventArgs e)
        {
            int counter = 0;
            bool completedsave = true;

            //Need to pull back all fields that are checked
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                if ((bool)dataGridView1.Rows[i].Cells["ApplyChanges"].FormattedValue)
                {
                    counter++;
                }
            }
            mycheckeditems = new CheckedItems[counter];
            counter = 0;
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                if ((bool)dataGridView1.Rows[i].Cells["ApplyChanges"].FormattedValue)
                {
                    mycheckeditems[counter].itemguid = new Guid(dataGridView1.Rows[i].Cells["FieldGuid"].Value.ToString());
                    mycheckeditems[counter].Value = dataGridView1.Rows[i].Cells["Value"].Value.ToString();
                    mycheckeditems[counter].LookupTableGuid = new Guid(dataGridView1.Rows[i].Cells["LookupTableGuid"].Value.ToString());
                    mycheckeditems[counter].Type = Convert.ToInt32(dataGridView1.Rows[i].Cells[9].Value.ToString());
                    String valguids = dataGridView1.Rows[i].Cells["ValueGuids"].Value.ToString();
                    String [] mystrs = valguids.Split(new Char[]{','}, valguids.Length);
                    mycheckeditems[counter].ValueGuids = new Guid[mystrs.Length];
                    for (int j = 0; j < mystrs.Length; j++)
                    {
                        mycheckeditems[counter].ValueGuids[j] = new Guid(mystrs[j]);
                    }

                    counter++;
                }
            }

            String Checkoutstr = "Successfully checked out :";
            //If we didn't do a resource bind now's the time to pull back the list of resources
            if (!resbind)
            {
                CreateListOfResources();
                for (int i = 0; i < RBSTypeNames.Length; i++)
                {
                    Checkoutstr += RBSTypeNames[i];
                    if (i > 0 || i != RBSTypeNames.Length) Checkoutstr += ",";
                }
            }

            String checkouterrormsg = "";
            //Now check out the resources
            int counter2 = 0;

            for(int z=0;z<resources.Length;z++)
            {
                try
                {
                    Guid[] tempguid = new Guid[1];
                    tempguid[0] = resources[z].resGuids;
                    Resource.CheckOutResources(tempguid);
                    if (resbind)
                    {
                        Checkoutstr += resources[counter2].resNames ;
                        if (counter2 > 0 || counter2 != resources.Length) Checkoutstr += ",";
                    }
                }
                catch (SoapException ex)
                {
                    //If it's CICO then it's a Check In Check Out error. We're not going to pop up
                    //a messagebox for each CICO error
                    completedsave = false;
                    if(ex.Message.Contains("CICO"))
                    {
                        checkouterrormsg += resources[counter2].resNames + " ;";
                    }
                    else
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                counter2++;
            }
            
            if (checkouterrormsg != "")
            {
                MessageBox.Show("Problem checking out: " + checkouterrormsg + " .This is most likely due to that resource(s) already being checked out");
            }

            for (int k = 0; k < resources.Length; k++)
            {
                ResourceWsc.ResourceDataSet myds = new ResourceWsc.ResourceDataSet();
                try
                {
                    myds = Resource.ReadResource(resources[k].resGuids);
                }
                catch (SoapException ex)
                {
                    completedsave = false;
                    MessageBox.Show(ex.Message);
                }

                for (int kk = 0; kk < counter; kk++)
                {
                    //This is the big update method
                    UpdateCFValue(mycheckeditems[kk], myds, resources[k].resGuids);
                }

                try
                {
                    Resource.UpdateResources(myds, false, true);
                }
                catch (SoapException ex)
                {
                    completedsave = false;
                    MessageBox.Show(ex.Message);
                }
            }
            uberlist = "";

            try
            {
                Guid[] tempgarr= new Guid[resources.Length];
                for (int l = 0; l < resources.Length; l++)
                {
                    tempgarr[l] = resources[l].resGuids;
                }
                Resource.CheckInResources(tempgarr, false);
            }
            catch (SoapException ex)
            {
                if (!ex.Message.Contains("CICONotCheckedOut"))
                {
                    //We don't care if the resource is already checked in
                    completedsave = false;
                    MessageBox.Show(ex.Message);
                }
            }
            if (completedsave)
            {
                MessageBox.Show("Updated Resource(s) successfully");
            }
            else
            {
                MessageBox.Show("Issues updating Resource(s)");
            }
        }

        //If you selected RBS nodes then this will work out the list of resources under those nodes
        private void CreateListOfResources()
        {
            ArrayList myalist1 = new ArrayList();
            ArrayList myalist2 = new ArrayList();
            for (int i = 0; i < RBSValueTypeGuids.Length; i++)
            {
                String connectionstring = "Integrated Security=true;database=" + RdbDatabase + ";server=" + RdbServer + ";";
                String commandstring = "";
                DataSet ResourceDS = new DataSet();
                commandstring += "select ResUserView.ResourceUID, ResUserView.ResourceName ";
                commandstring += "from MSP_EpmResource_UserView ResUserView INNER JOIN MSP_EpmLookupTable LT ON ";
                commandstring += "ResUserView.RBS = CAST(LT.MemberFullValue AS nvarchar(255)) AND ResUserView.ResourceType ='2' ";
                commandstring += "AND LT.LookupTableUID = '00008E67-65A3-4898-BAAA-D82D995BBB02' AND LT.MemberUID = '" + RBSValueTypeGuids[i].ToString() + "'";

                SqlConnection myconn = new SqlConnection(connectionstring);
                SqlDataAdapter myadp = new SqlDataAdapter(commandstring, myconn);
                myadp.Fill(ResourceDS);
                if (ResourceDS.Tables[0].Rows.Count > 0)
                {
                    for(int j=0; j<ResourceDS.Tables[0].Rows.Count; j++)
                    {
                        myalist1.Add(new Guid(ResourceDS.Tables[0].Rows[j].ItemArray[0].ToString()));
                        myalist2.Add(ResourceDS.Tables[0].Rows[j].ItemArray[1].ToString());
                    }
                }
            }
            if (myalist1.Count > 0)
            {
                resources = new SelectedResources[myalist1.Count];
                for (int k = 0; k < myalist1.Count; k++)
                {
                    resources[k].resGuids = new Guid(myalist1[k].ToString());
                    resources[k].resNames = myalist2[k].ToString();
                }
            }
        }

        private ResourceWsc.ResourceDataSet.ResourceCustomFieldsRow AddNewRow(ResourceWsc.ResourceDataSet myds, Guid resguid, Guid itemguid, int cftype)
        {
            ResourceWsc.ResourceDataSet.ResourceCustomFieldsRow myrow;
            myrow = myds.ResourceCustomFields.NewResourceCustomFieldsRow();
            myrow.RES_UID = resguid;
            myrow.MD_PROP_UID = itemguid;
            myrow.FIELD_TYPE_ENUM = (byte)cftype;
            myrow.CUSTOM_FIELD_UID = Guid.NewGuid();
            return myrow;
        }

        private void UpdateCFValue(CheckedItems mycheckeditems, ResourceWsc.ResourceDataSet myds, Guid resguid)
        {
            String filterstr = "";
            bool newrow = false;
            filterstr = "MD_PROP_UID = '" + mycheckeditems.itemguid.ToString() + "' AND RES_UID = '" + resguid.ToString() + "'";
            ResourceWsc.ResourceDataSet.ResourceCustomFieldsRow myrow = null;
            DataRow[] temprow =  myds.Tables["ResourceCustomFields"].Select(filterstr);

            int cfval = mycheckeditems.Type;
            if (temprow.Length > 0)
            {
                //Update existing row
                myrow = temprow[0] as ResourceWsc.ResourceDataSet.ResourceCustomFieldsRow;
            }
            else
            {
                //If it's a not a multivalue lookup then we'll add just one new row
                if(cfval != (int)PSLibrary.PSDataType.STRING && mycheckeditems.LookupTableGuid == null)
                {
                    newrow = true;
                    myrow = AddNewRow(myds, resguid, mycheckeditems.itemguid,cfval);
                }
            }
            switch (cfval)
            {
                case (int)PSLibrary.PSDataType.GUID:
                    myrow.CODE_VALUE = new Guid(mycheckeditems.Value);
                    break;
                case (int)PSLibrary.PSDataType.DATE:
                    myrow.DATE_VALUE = Convert.ToDateTime(mycheckeditems.Value);
                    break;
                case (int)PSLibrary.PSDataType.DURATION:
                    myrow.DUR_VALUE = Convert.ToInt32(mycheckeditems.Value);
                    break;
                case (int)PSLibrary.PSDataType.YESNO:
                    myrow.FLAG_VALUE = Convert.ToBoolean(mycheckeditems.Value);
                    break;
                case (int)PSLibrary.PSDataType.NUMBER:
                    myrow.NUM_VALUE = Convert.ToInt32(mycheckeditems.Value);
                    break;
                case (int)PSLibrary.PSDataType.STRING:
                    if (mycheckeditems.LookupTableGuid != null)
                    {
                        //It's not a true string, it's actually driven by a Lookup Table 
                        for (int j = 0; j < temprow.Length; j++)
                        {
                            temprow[j].Delete();
                        }
                        for (int k = 0; k < mycheckeditems.ValueGuids.Length; k++)
                        {
                            myrow = AddNewRow(myds, resguid, mycheckeditems.itemguid,cfval);                            
                            myrow.FIELD_TYPE_ENUM = (int)PSLibrary.PSDataType.STRING;
                            myrow.CODE_VALUE = mycheckeditems.ValueGuids[k];
                            myds.ResourceCustomFields.AddResourceCustomFieldsRow(myrow);
                            newrow = false;
                        }
                    }
                    else
                    {
                        //It's just a plain string
                        myrow.TEXT_VALUE = mycheckeditems.Value;
                    }
                    break;
                default:
                    break;
            }
            if (newrow)
            {
                myds.ResourceCustomFields.AddResourceCustomFieldsRow(myrow);
            }
        }

        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            DialogResult dr = DialogResult.Cancel;
            if (e.RowIndex != -1)
            {
                if (dataGridView1.Columns[e.ColumnIndex].Name == "Button")
                {
                    DataGridViewDisableButtonCell buttonCell =
                        (DataGridViewDisableButtonCell)dataGridView1.
                        Rows[e.RowIndex].Cells["Button"];


                    if (e.RowIndex == 0 || e.RowIndex == 1)
                    {
                        //Clicked Timesheet Owner
                        PeoplePicker picker = new PeoplePicker();
                        if (e.RowIndex == 0)
                            picker.defaultassignmentowner = false;
                        else
                            picker.defaultassignmentowner = true;
                        picker.PopulateControl();
                        dr = picker.ShowDialog();
                        String UserName = picker.SelectedUserName;
                        Guid UserGuid =  picker.SelectedUserGuid;
                        dataGridView1.Rows[e.RowIndex].Cells["Value"].Value = UserName;
                        dataGridView1.Rows[e.RowIndex].Cells["ValueGuids"].Value = UserGuid;
                    }
                    else if (BulkEdit.buttonactivationarray[e.RowIndex])
                    {
                        Guid tempCFguid = new Guid(dataGridView1.Rows[e.RowIndex].Cells["FieldGuid"].Value.ToString());
                        Guid tempLTGuid = new Guid(dataGridView1.Rows[e.RowIndex].Cells["LookupTableGuid"].Value.ToString());
                        //This is the multivalue field. Not sure why but for some reason specifying "MultiValue" doesn't work anymore!
                        Boolean tempMultiselect = (bool)dataGridView1.Rows[e.RowIndex].Cells[8].Value;
                        LookupTablePicker ltpicker = new LookupTablePicker();
                        ltpicker.CustomFieldGuid = tempCFguid;
                        ltpicker.LookupTableGuid = tempLTGuid;
                        ltpicker.multiselect = tempMultiselect;
                        ltpicker.PopulateControl();
                        dr = ltpicker.ShowDialog();
                        ArrayList lt = ltpicker.selecteditems;
                        String itemsnames = "";
                        String itemguids = "";
                        if (lt != null)
                        {
                            for (int i = 0; i < lt.Count; i++)
                            {
                                TreeNode temptn = (TreeNode)lt[i];
                                if (i != lt.Count - 1)
                                {
                                    itemsnames = itemsnames + temptn.Text + ", ";
                                    itemguids = itemguids + temptn.Name + ", ";
                                }
                                else
                                {
                                    itemsnames = itemsnames + temptn.Text;
                                    itemguids = itemguids + temptn.Name;
                                }
                            }
                        }
                        dataGridView1.Rows[e.RowIndex].Cells["Value"].Value = itemsnames;
                        dataGridView1.Rows[e.RowIndex].Cells["ValueGuids"].Value = itemguids;
                    }
                    if (dr == DialogResult.OK)
                        dataGridView1.Rows[e.RowIndex].Cells["ApplyChanges"].Value = true;
                }
            }
        }

        public void UpdateResources()
        {

        }

    }

    public class DataGridViewDisableButtonColumn : DataGridViewButtonColumn
    {
        public DataGridViewDisableButtonColumn()
        {
            this.CellTemplate = new DataGridViewDisableButtonCell();
            this.UseColumnTextForButtonValue = false;
        }
    }

    public class DataGridViewDisableButtonCell : DataGridViewButtonCell
    {
        public bool enabledValue=false;
        public bool Enabled
        {
            get
            {
                return enabledValue;
            }
            set
            {
                enabledValue = value;
            }
            
        }

        // Override the Clone method so that the Enabled property is copied.
        public override object Clone()
        {
            DataGridViewDisableButtonCell cell =
                (DataGridViewDisableButtonCell)base.Clone();
            cell.Enabled = this.Enabled;
            return cell;
        }

        // By default, enable the button cell.
        public DataGridViewDisableButtonCell()
        {
            this.enabledValue = true;
        }

        protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
        {
//            return base.GetFormattedValue(value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
            return "...";
        }

        protected override void Paint(Graphics graphics,
            Rectangle clipBounds, Rectangle cellBounds, int rowIndex,
            DataGridViewElementStates elementState, object value,
            object formattedValue, string errorText,
            DataGridViewCellStyle cellStyle,
            DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts)
        {
            // The button cell is disabled, so paint the border,  
            // background, and disabled button for the cell.

            if(!BulkEdit.buttonactivationarray[rowIndex])
            {
                // Draw the cell background, if specified.
                if ((paintParts & DataGridViewPaintParts.Background) ==
                    DataGridViewPaintParts.Background)
                {
                    SolidBrush cellBackground =
                        new SolidBrush(cellStyle.BackColor);
                    graphics.FillRectangle(cellBackground, cellBounds);
                    cellBackground.Dispose();
                }

                // Draw the cell borders, if specified.
                if ((paintParts & DataGridViewPaintParts.Border) ==
                    DataGridViewPaintParts.Border)
                {
                    PaintBorder(graphics, clipBounds, cellBounds, cellStyle,
                        advancedBorderStyle);
                }

                // Calculate the area in which to draw the button.
                Rectangle buttonArea = cellBounds;
                Rectangle buttonAdjustment =
                    this.BorderWidths(advancedBorderStyle);
                buttonArea.X += buttonAdjustment.X;
                buttonArea.Y += buttonAdjustment.Y;
                buttonArea.Height -= buttonAdjustment.Height;
                buttonArea.Width -= buttonAdjustment.Width;

                // Draw the disabled button.                
                ButtonRenderer.DrawButton(graphics, buttonArea,
                    PushButtonState.Disabled);
            }
            else
            {
                // The button cell is enabled, so let the base class 
                // handle the painting.
                base.Paint(graphics, clipBounds, cellBounds, rowIndex,
                    elementState, value, formattedValue, errorText,
                    cellStyle, advancedBorderStyle, paintParts);
            }
        }
    }

    public struct CheckedItems
    {
        public Guid itemguid;
        public String Value;
        public Guid LookupTableGuid;
        public Int32 Type;
        public Guid[] ValueGuids;
    }

    public struct SelectedResources
    {
        public Guid resGuids;
        public String resNames;
    }
}